#include "Solucao.h"
#include "FileSTS.h"

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

char *Solucao::print(){
        for(int i=0; i < tamanho; i++){
        	if(this->solucao[i] == true)
                	this->saida[i] = '1';
                else
                        this->saida[i] = '0';
        }
        this->saida[tamanho] = '\0';
        return this->saida;
}
	
void Solucao::loadEntrada(char *name){	
	FileSTS *f = new FileSTS();
	f->loadFile(name);
	
	tamanho = f->tamSteiner;
	numClient = f->tamClient;
	
	int tam = tamanho*numClient;

	linkClient = new double[tam];
	fcLinkClient = new double[tam];
	linkSteiner = new double[tamanho * tamanho];
	custoSteiner = new int[tamanho];
	capacidadeSteiner = new int[tamanho];	
	
	indClient = new int[tam];
	indServidor = new int[tam];
	indCusto = new double[tam];

	//Carregando Ligacao Cliente-Steiner			
	for(int i=0, k=0; i < f->tamSteiner; i++){
		for(int j=0; j < f->tamClient; j++){
			linkClient[k] = f->distanciaClientSteiner(i, j);
			indClient[k] = j;
			indServidor[k] = i;
			indCusto[k] = linkClient[k];
			++k;
		}
	}
	custoClientSteiner = new ListaAresta(tam);
	custoClientSteiner->insereOrdenado(indClient, indServidor, indCusto);

	//Carregando Ligacao Steiner-Steiner
	for(int i=0, k=0; i < f->tamSteiner; i++){
		for(int j=i+1; j < f->tamSteiner; j++){
			linkSteiner[k] = f->distanciaSteinerSteiner(i, j);
			++k;
		}
	}

	//Carrega custo Steiner
	for(int i=0; i<f->tamSteiner; i++){
		custoSteiner[i] = (int)f->custos[i];
		//printf("C: %d\n", custoSteiner[i]);
	}
	//Carrega capacidade dos Steiners e sua media
	for(int i=0; i<f->tamSteiner; i++){
		capacidadeSteiner[i] = f->capacidade[i];
		if(capacidadeSuperior < f->capacidade[i])
			capacidadeSuperior = f->capacidade[i];
	}

	delete f;
}

#define OUT "saida/"

void Solucao::printEntrada(){
	FILE *pf;
	
	if((pf = fopen("capacidade.data", "w") )==NULL){
        	printf("\nNao consigo abrir o arquivo capacidade.data!");
                exit(1);
	}
	
	for(int j=0; j<tamanho; j++){
		fprintf(pf, "%d\n", capacidadeSteiner[j]);
	}

	fclose(pf);	
	

	if((pf = fopen("client_steiner.data", "w") )==NULL){
        	printf("\nNao consigo abrir o arquivo client_steiner.data!");
                exit(1);
	}

	int k = 0;
	for(int i=0; i<tamanho; i++){
		char *steiner = new char[100000]; steiner[0]='\0';
		for(int j=0; j<numClient; j++){
			sprintf(steiner, "%s %f", steiner, linkClient[k]); k++;
		}
		fprintf(pf, "%s\n", steiner);
		delete steiner;
	}

	fclose(pf);	
	
	
	if((pf = fopen("steiner_steiner.data", "w") )==NULL){
        	printf("\nNao consigo abrir o arquivo steiner_steiner.data!");
                exit(1);
	}

	k = 0;
	for(int i=0; i<tamanho; i++){
		char *steiner = new char[1000]; steiner[0]='\0';
		for(int j=0; j<tamanho; j++){
			if(i>=j){
				sprintf(steiner, "%s %d", steiner, 0);
			}else{
				sprintf(steiner, "%s %f", steiner, linkSteiner[k]); k++;
			}
		}
		fprintf(pf, "%s\n", steiner);
		delete steiner;
	}

	fclose(pf);	

	
	if((pf = fopen("custo.data", "w") )==NULL){
        	printf("\nNao consigo abrir o arquivo custo.data!");
                exit(1);
	}
	for(int j=0; j<tamanho; j++){
		fprintf(pf, "%d\n", custoSteiner[j]);
	}
	
	fclose(pf);	
}

void Solucao::printResultado(){
	char name[100]; 
	FILE *pf;
	int tamLigacao = tamanho * numClient;
        int auxCapacidade[tamanho];
	
	sprintf(name, "%s%s%d%s%d%s", OUT, "s_", tamanho, "_c_", numClient, ".txt");

	//Alocando a saida do arquivo.
	char **saida = (char **)malloc(tamanho);
	for(int i=0; i<tamanho; i++){
		saida[i] = (char *)malloc(10000);
		saida[i][0] = '\0';
	}
        
	//Fazendo copia das capacidades
	for(int i=0; i < tamanho; i++)
                auxCapacidade[i] = capacidadeSteiner[i];
	
	for(int i=0; i<numClient; i++){
                double c = 10000000;
                int pos = 0;
                for(int j = 0, k = 0; j < tamanho; j++, k+=numClient){
                        if((this->solucao[j] == true)&&(auxCapacidade[j]!=0)){
                                if(c > linkClient[k + i]){
                                        c  = linkClient[k + i];
                                        pos = j;
                                }
                        }
                }
                sprintf(saida[pos], "%s%d ", saida[pos], i);
                auxCapacidade[pos]--;//printf("P: %d\n", pos);
        }

	if((pf = fopen(name, "w") )==NULL){
        	printf("\nNao consigo abrir o arquivo %s!", name);
                exit(1);
        }

	fprintf(pf, "Steiner\tClients\n");
	for(int i=0; i<tamanho; i++){
		if(this->solucao[i]){
			fprintf(pf, "%d\t%s\n", i, saida[i]);
		}
	}
		

	for(int i=0; i<tamanho; i++)
		free(saida[i]);
	//free(saida);
	fclose(pf);
}

void Solucao::initGulosa(){
	if(auxLinkClient)
		delete auxLinkClient;
	auxLinkClient = new double[numClient];
	isInitGulosa = true;
}

bool Solucao::isInitGulosa = true;
int Solucao::tamanho = 0;
int Solucao::numClient = 0;
double *Solucao::linkClient = 0;
double *Solucao::fcLinkClient = 0;
double *Solucao::auxLinkClient = NULL;
double *Solucao::linkSteiner = 0;
int *Solucao::custoSteiner = 0;
int *Solucao::capacidadeSteiner = 0;
int Solucao::capacidadeSuperior = 0;
ListaAresta *Solucao::custoClientSteiner;

double *Solucao::indCusto = 0;
int *Solucao::indServidor = 0;
int *Solucao::indClient = 0;

